/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hxg.portmgr.core.dao.impl.jaxb;

import hxg.portmgr.core.device.DeviceModel;
import hxg.portmgr.core.device.DeviceType;
import hxg.portmgr.core.dao.DeviceModelDAO;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

/**
 *
 * @author hxg
 */
public final class DeviceModelDAOJaxbImpl implements DeviceModelDAO {

    private static final Logger logger = Logger.getLogger(DeviceModelDAOJaxbImpl.class.getName());
    //设置为MAP的原因是要强制保证全局下一个oid只能对应一个型号
    //static LinkedHashMap<String,DeviceModel> DeviceModelTable=new LinkedHashMap<String, DeviceModel>();
    final TreeSet<DeviceModel> DeviceModelSet = new TreeSet();
    final File savefile = new File(".\\conf\\DeviceModel.xml");

    public DeviceModelDAOJaxbImpl() {
        load();
        if (!savefile.exists()) {
            savefile.getParentFile().mkdirs();
        }
    }

    @Override
    public void load() {
        List<DeviceModel> models = JaxbDecode(savefile);
        for (DeviceModel model : models) {
            logger.log(Level.INFO, "载入了型号[{0}],对应的sysOid={1}", new Object[]{model, model.getSysOid()});
        }
        DeviceModelSet.clear();
        DeviceModelSet.addAll(models);
    }

    @Override
    public void save() {
        JaxbEncode(savefile);
    }

    @Override
    public TreeSet<DeviceModel> getDeviceModels() {
        return DeviceModelSet;
    }

    @Override
    public DeviceModel addDeviceModel(DeviceModel m) {
        DeviceModelSet.add(m);
        return m;
    }

    @Override
    public DeviceModel getModelBySysOid(String oid) {
        if (oid == null || oid.isEmpty()) {
            return DeviceModel.getUnReachedAbleModel();
        }
        for (DeviceModel m : DeviceModelSet) {
            if (m.getSysOid().equals(oid)) {
                return m;
            }
        }
        DeviceModel m = new DeviceModel();
        m.setModelName(oid);
        m.setSysOid(oid);
        m.setType(DeviceType.OTHER);
        return m;
    }

    @Override
    public DeviceType getDeviceTypeBySysOid(String oid) {
        for (DeviceModel m : DeviceModelSet) {
            if (m.getSysOid().equals(oid)) {
                return m.getType();
            }
        }
        return DeviceType.OTHER;
    }

    public void JaxbEncode(File f) {
        OutputStream os = null;
        try {
            os = new FileOutputStream(f);
            JAXBContext jc = JAXBContext.newInstance(DeviceModelListBean.class);
            Marshaller m = jc.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            DeviceModelListBean dmlist = new DeviceModelListBean();
            dmlist.list.addAll(DeviceModelSet);
            m.marshal(dmlist, os);
        } catch (FileNotFoundException | JAXBException ex) {
            Logger.getLogger(DeviceModelDAOJaxbImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                os.close();
            } catch (IOException ex) {
                Logger.getLogger(DeviceModelDAOJaxbImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public List<DeviceModel> JaxbDecode(File f) {
        try {
            JAXBContext jc = JAXBContext.newInstance(DeviceModelListBean.class);
            Unmarshaller u = jc.createUnmarshaller();
            DeviceModelListBean dlist = (DeviceModelListBean) u.unmarshal(f);
            return dlist.list;
        } catch (JAXBException ex) {
            Logger.getLogger(DeviceModelDAOJaxbImpl.class.getName()).log(Level.SEVERE, null, ex);
            return new ArrayList<>();
        }
    }

    @Override
    public void removerDeviceModel(DeviceModel m) {
        DeviceModelSet.remove(m);
    }

    @Override
    public List<DeviceModel> getDeviceModelsOfType(DeviceType type) {
        List<DeviceModel> models = new ArrayList<DeviceModel>();
        for (DeviceModel m : getDeviceModels()) {
            if (m.getType().equals(type)) {
                models.add(m);
            }
        }
        return models;
    }
}
